﻿/***********************************************************************
 * <copyright file="BaseTreeListUserControl.cs" company="BUCA JSC">
 * -->    Copyright (C) statement. All right reserved
 * </copyright>
 * 
 * Created:   LinhMC
 * Email:    linhmc@buca.vn
 * Website:
 * Create Date: Monday, February 10, 2014
 * Usage: 
 * 
 * RevisionHistory: 
 * Date         Author               Description 
 * 
 * ************************************************************************/

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using System.Threading;
using System.Windows.Forms;
using WindowsForms.AOnline.Model.BusinessObjects.Report;
using WindowsForms.AOnline.Presenter.Report;
using WindowsForms.AOnline.Report.ReportClass;
using WindowsForms.AOnline.Session;
using WindowsForms.AOnline.View.Report;
using WindowsForms.AOnline.WindowsForm.FormBase;
using WindowsForms.AOnline.WindowsForm.FormBase.PropertyGrid;
using WindowsForms.AOnline.WindowsForm.Resources;
using DevExpress.XtraEditors;
using DevExpress.XtraTreeList.Columns;
using DevExpress.XtraTreeList.Data;
using SummaryItemType = DevExpress.XtraTreeList.SummaryItemType;


namespace WindowsForms.AOnline.WindowsForm.BaseUserControls
{
    public partial class BaseTreeListUserControl : XtraUserControl, IReportView
    {
        private readonly ReportListPresenter _reportListPresenter;
        private List<ReportListModel> _reportList;

        #region Variables

        /// <summary>
        /// 
        /// </summary>
        public enum ActionMode
        {
            /// <summary>
            /// The add new
            /// </summary>
            AddNew = 0,
            /// <summary>
            /// The edit
            /// </summary>
            Edit = 1,
            /// <summary>
            /// The delete
            /// </summary>
            Delete = 2,
            /// <summary>
            /// The none
            /// </summary>
            None = 3
        }

        /// <summary>
        /// The e action mode
        /// </summary>
        public ActionMode eActionMode;

        /// <summary>
        /// The columns collection
        /// </summary>
        public List<XtraColumn> ColumnsCollection = new List<XtraColumn>();

        /// <summary>
        /// The primary key value
        /// </summary>
        public string PrimaryKeyValue;

        /// <summary>
        /// The current page
        /// </summary>
        public static int CurrentPage=1;

        public static int TotalPage = 0;  
        #endregion

        #region Properties

        /// <summary>
        /// Gets or sets the form detail.
        /// </summary>
        /// <value>
        /// The form detail.
        /// </value>
        [Category("BaseProperty")]
        public string FormDetail { get; set; }

        /// <summary>
        /// Gets or sets the namespace form.
        /// </summary>
        /// <value>
        /// The namespace form.
        /// </value>
        [Category("BaseProperty")]
        public string NamespaceForm { get; set; }

        /// <summary>
        /// Gets or sets the table primary key.
        /// </summary>
        /// <value>
        /// The table primary key.
        /// </value>
        [Category("BaseProperty")]
        public string TablePrimaryKey { get; set; }

        /// <summary>
        /// Gets or sets the report identifier.
        /// </summary>
        /// <value>
        /// The report identifier.
        /// </value>
        [Category("BaseProperty")]
        public string ReportID { get; set; }

        /// <summary>
        /// Gets or sets the form caption.
        /// </summary>
        /// <value>
        /// The form caption.
        /// </value>
        [Category("BaseProperty")]
        public string FormCaption { get; set; }

        /// <summary>
        /// Gets or sets the row selected.
        /// </summary>
        /// <value>
        /// The row selected.
        /// </value>
        [Category("BaseProperty")]
        public int RowSelected { get; set; }

        /// <summary>
        /// Gets or sets the name of the parent field.
        /// </summary>
        /// <value>
        /// The name of the parent field.
        /// </value>
        [Category("BaseProperty")]
        public string ParentFieldName { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether [expand all].
        /// </summary>
        /// <value>
        ///   <c>true</c> if [expand all]; otherwise, <c>false</c>.
        /// </value>
        [Category("BaseProperty")]
        public bool ExpandAll { get; set; }

        /// <summary>
        /// Gets or sets the active node.
        /// </summary>
        /// <value>
        /// The active node.
        /// </value>
        public object ActiveNode { get; set; }

        #endregion

        #region Functions

        /// <summary>
        /// Initializes the layout.
        /// </summary>
        private void InitializeLayout()
        {
            Text = FormCaption;
            eActionMode = ActionMode.None;
        }

        /// <summary>
        /// Loads the data.
        /// </summary>
        private void LoadData()
        {
            try
            {
                if (CurrentPage>0) 
                {              
                treeList.BeginUpdate();
                InitializeTreeMain();
                LoadDataIntoTree(CurrentPage);
                LoadGridLayout();
                SetTreeListNumericFormat();
                if (CurrentPage <= TotalPage)
                    {                                           
                lblPage.Text = @"Trang " + CurrentPage.ToString() + @"/" + TotalPage.ToString();
                    }
            }
            }
            catch (Exception ex)
            {
                XtraMessageBox.Show(ex.Message, ResourceHelper.GetResourceValueByName("ResExceptionCaption"));
                treeList.EndUpdate();
            }
            finally
            {
                treeList.EndUpdate();
                eActionMode = ActionMode.None;
            }
        }

        /// <summary>
        /// Loads the grid layout.
        /// </summary>
        private void LoadGridLayout()
        {
            if (ColumnsCollection != null)
            {
                foreach (var column in ColumnsCollection)
                {
                    if (column.ColumnVisible)
                    {
                        treeList.Columns[column.ColumnName].Caption = column.ColumnCaption;
                        treeList.Columns[column.ColumnName].VisibleIndex = column.ColumnPosition;
                        treeList.Columns[column.ColumnName].Width = column.ColumnWith;
                        treeList.Columns[column.ColumnName].AppearanceHeader.TextOptions.HAlignment = column.Alignment;
                        treeList.Columns[column.ColumnName].UnboundType = (UnboundColumnType) column.ColumnType;
                    }
                    else treeList.Columns[column.ColumnName].Visible = false;
                }
            }
            if (ExpandAll) treeList.ExpandAll();
            else treeList.CollapseAll();

            //ExpandAll
            treeList.ExpandAll();
        }

        /// <summary>
        /// Sets the tree list numeric format.
        /// </summary>
        protected virtual void SetTreeListNumericFormat()
        {
            foreach (TreeListColumn oCol in treeList.Columns)
            {
                if (!oCol.Visible) continue;
                switch (oCol.UnboundType)
                {
                    case DevExpress.XtraTreeList.Data.UnboundColumnType.Decimal:
                        oCol.Format.FormatString = GlobalVariable.CurrencyDisplayString;
                        oCol.Format.Format = Thread.CurrentThread.CurrentCulture.NumberFormat;
                        oCol.SummaryFooter = (SummaryItemType) DevExpress.Data.SummaryItemType.Sum;
                        oCol.SummaryFooterStrFormat = GlobalVariable.CurrencyDisplayString;
                        break;
                    case DevExpress.XtraTreeList.Data.UnboundColumnType.Integer:
                        oCol.Format.FormatString = GlobalVariable.NumericDisplayString;
                        oCol.Format.Format = Thread.CurrentThread.CurrentCulture.NumberFormat;
                        break;
                    case DevExpress.XtraTreeList.Data.UnboundColumnType.DateTime:
                        oCol.Format.FormatString = Thread.CurrentThread.CurrentCulture.DateTimeFormat.ShortDatePattern;
                        oCol.Format.Format = Thread.CurrentThread.CurrentCulture.DateTimeFormat;
                        break;
                }
            }
        }

        /// <summary>
        /// Initializes the tree main.
        /// </summary>
        private void InitializeTreeMain()
        {
            treeList.ParentFieldName = ParentFieldName;
            treeList.KeyFieldName = TablePrimaryKey;
        }

        /// <summary>
        /// Sets the row selected.
        /// </summary>
        /// <param name="nodeHandler">The node handler.</param>
        private void SetRowSelected(int nodeHandler = 0)
        {
            treeList.OptionsSelection.EnableAppearanceFocusedRow = true;
            treeList.OptionsSelection.EnableAppearanceFocusedCell = false;
            if (treeList.Nodes.Count > 0) treeList.FocusedNode = treeList.Nodes[nodeHandler];
            else GetRowValueSelected();
        }

        /// <summary>
        /// Gets the row value selected.
        /// </summary>
        public void GetRowValueSelected()
        {
            try
            {
                if (eActionMode == ActionMode.None || eActionMode == ActionMode.Delete)
                    PrimaryKeyValue = treeList.Nodes.Count > 0 ? treeList.FocusedNode[treeList.KeyFieldName].ToString() : null;
            }
            catch (Exception ex)
            {
                XtraMessageBox.Show(ex.Message, ResourceHelper.GetResourceValueByName("ResExceptionCaption"));
            }
        }

        /// <summary>
        /// Shows the form detail.
        /// </summary>
        private void ShowFormDetail()
        {
            try
            {
                using (var frmDetail = GetFormDetail())
                {
                    frmDetail.KeyFieldName = TablePrimaryKey;
                    frmDetail.ParentName = ParentFieldName;
                    frmDetail.ActionMode = (FrmXtraBaseTreeDetail.ActionModeEnum)eActionMode;
                    frmDetail.KeyValue = frmDetail.ActionMode == FrmXtraBaseTreeDetail.ActionModeEnum.AddNew ? null : PrimaryKeyValue;
                    frmDetail.HasChildren = PrimaryKeyValue != null && treeList.FindNodeByKeyID(int.Parse(PrimaryKeyValue)).HasChildren;
                    frmDetail.CurrentNode = treeList.Nodes.Count > 0 ? ActiveNode : null;
                    frmDetail.PostKeyValue += FrmDetail_PostKey;
                    if (frmDetail.ShowDialog() == DialogResult.OK) { }
                }
            }
            catch (Exception ex) { XtraMessageBox.Show(ex.Message, ResourceHelper.GetResourceValueByName("ResExceptionCaption"), MessageBoxButtons.OK, MessageBoxIcon.Error); }
        }

        /// <summary>
        /// Gets the form detail.
        /// </summary>
        /// <returns></returns>
        private FrmXtraBaseTreeDetail GetFormDetail()
        {
            try
            {
                Type typeOfForm = Assembly.GetExecutingAssembly().GetType(NamespaceForm + "." + FormDetail);
                return typeOfForm != null ? (FrmXtraBaseTreeDetail)Activator.CreateInstance(typeOfForm) : null;
            }
            catch (Exception ex)
            {
                XtraMessageBox.Show(ex.Message, ResourceHelper.GetResourceValueByName("ResExceptionCaption"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                return null;
            }
        }

        /// <summary>
        /// Sets the row after update.
        /// </summary>
        private void SetRowAfterUpdate()
        {
            if (PrimaryKeyValue == null)
                return;
            if (treeList.Nodes.Count > 0) treeList.FocusedNode = treeList.FindNodeByKeyID(int.Parse(PrimaryKeyValue));
            else SetRowSelected();
        }

        /// <summary>
        /// FRMs the detail_ post key.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="data">The data.</param>
        public void FrmDetail_PostKey(object sender, string data)
        {
            PrimaryKeyValue = data;
        }

        /// <summary>
        /// Refreshes the toolbar.
        /// </summary>
        protected virtual void RefreshToolbar()
        {
            barButtonEditItem.Enabled = treeList.Nodes.Count > 0;
            barButtonDeleteItem.Enabled = treeList.Nodes.Count > 0;
            barButtonPrintItem.Enabled = treeList.Nodes.Count > 0;
            barButtonFindItem.Enabled = treeList.Nodes.Count > 0;
        }

        #endregion

        #region Functions overrides

        /// <summary>
        /// Loads the data into tree.
        /// </summary>
        protected virtual void LoadDataIntoTree(int page)
        {
        }

        /// <summary>
        /// Deletes the tree.
        /// </summary>
        protected virtual string DeleteTree()
        {
            return "";
        }

        /// <summary>
        /// Adds the data.
        /// </summary>
        protected virtual void AddData()
        {
            eActionMode = ActionMode.AddNew;
            ShowFormDetail();
            LoadData();
        }

        /// <summary>
        /// Edits the data.
        /// </summary>
        protected virtual void EditData()
        {
            eActionMode = ActionMode.Edit;
            ShowFormDetail();
            LoadData();
        }

        /// <summary>
        /// Prints the data.
        /// </summary>
        protected virtual void PrintData()
        {
            try
            {
                eActionMode = ActionMode.None;
                Cursor.Current = Cursors.WaitCursor;
                var reportHelper = new ReportHelper();
                _reportList = _reportListPresenter.GetAllReportList();
                reportHelper.ReportLists = _reportList;
                reportHelper.PrintPreviewReport(null, ReportID, false);
            }
            catch (Exception ex)
            {
                XtraMessageBox.Show(ex.ToString(), "Thông báo", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                Cursor.Current = Cursors.Default;
            }
        }

        /// <summary>
        /// Helps this instance.
        /// </summary>
        protected virtual void Help()
        {

        }

        #endregion

        /// <summary>
        /// Initializes a new instance of the <see cref="BaseTreeListUserControl"/> class.
        /// </summary>
        public BaseTreeListUserControl()
        {
            InitializeComponent();
            _reportListPresenter = new ReportListPresenter(this);
        }

        /// <summary>
        /// Handles the Load event of the BaseTreeListUserControl control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
        private void BaseTreeListUserControl_Load(object sender, EventArgs e)
        {
            InitializeLayout();
            LoadData();
            SetRowSelected(RowSelected);
            RefreshToolbar();
            treeList.ExpandAll();
            treeList.Focus();
        }

        /// <summary>
        /// Handles the AfterFocusNode event of the treeList control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="DevExpress.XtraTreeList.NodeEventArgs"/> instance containing the event data.</param>
        private void treeList_AfterFocusNode(object sender, DevExpress.XtraTreeList.NodeEventArgs e)
        {

        }

        /// <summary>
        /// Handles the DoubleClick event of the treeList control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
        private void treeList_DoubleClick(object sender, EventArgs e)
        {
            EditData();
            SetRowAfterUpdate();
        }

        /// <summary>
        /// Handles the ItemClick event of the barToolManager control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="DevExpress.XtraBars.ItemClickEventArgs"/> instance containing the event data.</param>
        private void barToolManager_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            switch (e.Item.Name)
            {
                case "barButtonAddNewItem":
                    AddData();
                    SetRowAfterUpdate();
                    break;
                case "barButtonEditItem":
                    EditData();
                    SetRowAfterUpdate();
                    break;
                case "barButtonDeleteItem":
                    try
                    {
                        eActionMode = ActionMode.Delete;
                        var result = XtraMessageBox.Show(ResourceHelper.GetResourceValueByName("ResDeleteContent"), ResourceHelper.GetResourceValueByName("ResDeleteCaption"),
                                                                MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
                        if (result == DialogResult.OK)
                        {
                            if (treeList.FindNodeByKeyID(int.Parse(PrimaryKeyValue)).HasChildren) 
                                XtraMessageBox.Show(ResourceHelper.GetResourceValueByName("ResDeleteTreeHasChild"), 
                                    ResourceHelper.GetResourceValueByName("ResDeleteCaption"),
                                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                            else
                            {

                                var errorMess = DeleteTree();
                                if (errorMess == null)
                                {
                                    XtraMessageBox.Show(ResourceHelper.GetResourceValueByName("ResDeleteResult"),
                                                     ResourceHelper.GetResourceValueByName("ResDeleteCaption"),
                                                     MessageBoxButtons.OK, MessageBoxIcon.Information);

                                }
                                else
                                {
                                    XtraMessageBox.Show(errorMess, ResourceHelper.GetResourceValueByName("ResExceptionCaption"));
                                }
                            }
                        }
                    }
                    catch (Exception ex) { XtraMessageBox.Show(ex.Message, ResourceHelper.GetResourceValueByName("ResExceptionCaption")); }
                    finally
                    {
                        LoadData();
                        SetRowSelected();
                    }
                    break;
                case "barButtonRefeshItem":
                    LoadData();
                    SetRowSelected();
                    break;
                case "barButtonPrintItem":
                    PrintData();
                    break;
                case "barButtonHelpItem":
                    Help();
                    break;
            }
            RefreshToolbar();
        }

        /// <summary>
        /// Handles the FocusedNodeChanged event of the treeList control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="DevExpress.XtraTreeList.FocusedNodeChangedEventArgs"/> instance containing the event data.</param>
        private void treeList_FocusedNodeChanged(object sender, DevExpress.XtraTreeList.FocusedNodeChangedEventArgs e)
        {
            var node = e.Node;
            if (node == null)
                return;
            GetRowValueSelected();
            ActiveNode = treeList.GetDataRecordByNode(node);
        }

        #region IReportView Members

        /// <summary>
        /// Gets or sets the report lists.
        /// </summary>
        /// <value>
        /// The report lists.
        /// </value>
        public List<ReportListModel> ReportLists
        {
            get
            {
                return _reportList;
            }
            set
            {
                _reportList = value;
            }
        }

        #endregion

        private void btnNext_Click(object sender, EventArgs e)
        {
            CurrentPage = CurrentPage + 1;
            if (CurrentPage>TotalPage)
            {
                CurrentPage = TotalPage;
            }
            LoadData();
        }

        private void btnPre_Click(object sender, EventArgs e)
        {
            CurrentPage = CurrentPage - 1;
            if (CurrentPage==0)
            {
                CurrentPage = 1;
            }
            LoadData();
        }

        private void btnLast_Click(object sender, EventArgs e)
        {
            CurrentPage = TotalPage;
            LoadData();
        }

        private void btnFirst_Click(object sender, EventArgs e)
        {
            CurrentPage = 1;
            LoadData();
        }
    }
}
